﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Drawing;
using System.Xml;
using System.Collections;
using System.Text;
using System.IO;
using System.Drawing.Imaging;
using System.Security.Cryptography;

namespace _4SquareLite
{
    static class Program
    {
        public static int iScrollbarWidth = 13;

        public static ArrayList arrForm;

        public static bool bSendToTwitter = false;
        public static bool bSendToFacebook = false;

        public static string strGlobalLat;
        public static string strGlobalLon;

        public static string strProgramName = "4SquareLite";
        public static string strProgramVersion = "2010.08.05.16.50";
        public static bool bLogging = false;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main()
        {
            arrForm = new ArrayList();

            string strAuthenticat = LocalSettings.LoadString("Authentication");
            if (String.IsNullOrEmpty(strAuthenticat))
            {
                Application.Run(new frmLogin());
            }
            else
            {
                Cursor.Current = Cursors.WaitCursor;
                string strResult = HttpGet("http://api.foursquare.com/v1/user");
                Cursor.Current = Cursors.Default;

                if (String.IsNullOrEmpty(strResult))
                {
                    Application.Run(new frmLogin());
                }
                else
                {
                    Application.Run(new frmDashboard(strResult));
                }
            }
        }

        //http://stackoverflow.com/questions/2396288/how-to-get-an-image-to-a-picturebox-from-an-url-windows-mobile
        public static Bitmap getImageFromURL(string strURL)
        {
            System.Drawing.Bitmap bmpReturn = null;

            string strFilename = CalculateMD5Hash(strURL);
            string strExtension = ".png";
            if (strURL.Contains(".jpg"))
            {
                strExtension = ".jpg";
            }
            strFilename += strExtension;

            string strCachePath = "\\Storage Card\\My Pictures\\4SquareLite\\";
            if (!Directory.Exists(strCachePath))
            {
                Directory.CreateDirectory(strCachePath);
            }

            //search cache
            if (File.Exists(strCachePath + strFilename))
            {
                bmpReturn = new Bitmap(strCachePath + strFilename);
            }
            else
            {
                try
                {
                    HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(strURL);
                    myRequest.Method = "GET";
                    HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
                    bmpReturn = new Bitmap(myResponse.GetResponseStream());
                    myResponse.Close();
                }
                catch
                {
                    MessageBox.Show("Oops! We couldn't get an image from the Internet. We'll try again later.", "getImageFromURL",
                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                }

                ImageFormat oImageFormat = ImageFormat.Png;
                if (strFilename.ToLower().Contains(".jpg"))
                {
                    oImageFormat = ImageFormat.Jpeg;
                }

                try
                {
                    if (bmpReturn != null)
                    {
                        bmpReturn.Save(strCachePath + strFilename, oImageFormat);
                    }
                }
                catch
                {
                    MessageBox.Show("Oops! We couldn't save an image into the cache. We'll try again next time.", "getImageFromURL",
                        MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                }
            }

            return bmpReturn;
        }

        public static string getInnerText(XmlNode xmlParentNode, string strChildNode)
        {
            string strReturn = "";

            XmlNode xmlThisNode = xmlParentNode.SelectSingleNode(strChildNode);
            if (xmlThisNode != null)
            {
                strReturn = xmlThisNode.InnerText;
                strReturn = strReturn.Replace("&", "&&");
            }

            return strReturn;
        }

        public static string getGoogleMapURL(string strLat, string strLon, Size size, bool bSensor)
        {
            return "http://maps.google.com/maps/api/staticmap?center=" + strLat + "," + strLon + "&zoom=15&size=" + size.Width + "x" + size.Height + "&maptype=roadmap&mobile=true&sensor=" + bSensor + "&markers=size:small|color:blue|" + strLat + "," + strLon;
        }

        //http://en.csharp-online.net/HTTP_Post
        public static string HttpPost(string strURL, string strParameters)
        {
            string strReturn = null;

            // strParameters: name1=value1&name2=value2

            string strAuthentication = LocalSettings.LoadString("Authentication");
            if (!String.IsNullOrEmpty(strAuthentication))
            {
                HttpWebRequest oRequest = (HttpWebRequest)WebRequest.Create(strURL);
                oRequest.ContentType = "application/x-www-form-urlencoded";
                oRequest.Method = "POST";
                oRequest.Headers["Authorization"] = "Basic " + strAuthentication;
                oRequest.UserAgent = "foursquarelite" + strProgramVersion;

                byte[] arrBytes = Encoding.ASCII.GetBytes(strParameters);
                Stream oOutStream = null;
                try
                {
                    // send the Post
                    oRequest.ContentLength = arrBytes.Length;   //Count bytes to send
                    oOutStream = oRequest.GetRequestStream();
                    oOutStream.Write(arrBytes, 0, arrBytes.Length);         //Send it
                }
                catch
                {
                    MessageBox.Show("Oops! We couldn't get data from the Internet. Try again later.", "HttpPost: Request error",
                       MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                }
                finally
                {
                    if (oOutStream != null)
                    {
                        oOutStream.Close();
                    }
                }

                try
                {
                    // get the response
                    HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse();

                    if (oResponse == null)
                    {
                        strReturn = null;
                    }

                    StreamReader oInStream = new StreamReader(oResponse.GetResponseStream());

                    strReturn = oInStream.ReadToEnd().Trim();
                    oInStream.Close();
                }
                catch
                {
                    MessageBox.Show("Oops! We couldn't post data to the Internet. Try again later.", "HttpPost: Response error",
                       MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                }

                if (bLogging)
                {
                    /////////////////////////////////////////////////////////////////////////
                    // write to log
                    // create a writer and open the file
                    string strFilename = DateTime.Now.ToString("yyMMddhhmmss") + "-P.txt";
                    TextWriter tw = new StreamWriter(strFilename);

                    // write a line of text to the file
                    tw.WriteLine(strURL);
                    tw.WriteLine(strParameters);
                    tw.WriteLine(strReturn);

                    // close the stream
                    tw.Close();
                }
            }

            return strReturn;
        }

        public static string HttpGet(string strURL)
        {
            string strReturn = null;
            // strParameters: name1=value1&name2=value2

            string strAuthentication = LocalSettings.LoadString("Authentication");
            if (!String.IsNullOrEmpty(strAuthentication))
            {

                HttpWebRequest oRequest = (HttpWebRequest)WebRequest.Create(strURL);
                oRequest.Headers["Authorization"] = "Basic " + strAuthentication;
                oRequest.UserAgent = "SUF 4SQLite:20100530";

                try
                {
                    // get the response
                    HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse();

                    if (oResponse == null)
                    {
                        strReturn = null;
                    }

                    StreamReader oInStream = new StreamReader(oResponse.GetResponseStream());

                    strReturn = oInStream.ReadToEnd().Trim();
                    oInStream.Close();
                }
                catch
                {
                    MessageBox.Show("Oops! We can't get data from the Internet. Try again later.", "HttpGet: Response error",
                       MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                }

                if (bLogging)
                {
                    /////////////////////////////////////////////////////////////////////////
                    // write to log
                    // create a writer and open the file
                    string strFilename = DateTime.Now.ToString("yyMMddhhmmss") + "-G.txt";
                    TextWriter tw = new StreamWriter(strFilename);

                    // write a line of text to the file
                    tw.WriteLine(strURL);
                    tw.WriteLine(strReturn);

                    // close the stream
                    tw.Close();
                }
            }

            return strReturn;
        }

        public static string convertAPITimeToLocalTime(string strCreated)
        {
            string strReturn = "";

            if (!String.IsNullOrEmpty(strCreated))
            {
                //Mon, 21 Jun 10 13:52:41 +0000

                //21 Jun 10 13:52:41 +0000
                strCreated = strCreated.Remove(0, 5);

                //21 Jun 10 13:52:41
                strCreated = strCreated.Remove(strCreated.Length - 6, 6);

                strCreated = strCreated.Replace("Jan", "1");
                strCreated = strCreated.Replace("Feb", "2");
                strCreated = strCreated.Replace("Mar", "3");
                strCreated = strCreated.Replace("Apr", "4");
                strCreated = strCreated.Replace("May", "5");
                strCreated = strCreated.Replace("Jun", "6");
                strCreated = strCreated.Replace("Jul", "7");
                strCreated = strCreated.Replace("Aug", "8");
                strCreated = strCreated.Replace("Sep", "9");
                strCreated = strCreated.Replace("Oct", "10");
                strCreated = strCreated.Replace("Nov", "11");
                strCreated = strCreated.Replace("Dec", "12");

                strCreated = strCreated.Replace(":", " ");

                string[] arrString = strCreated.Split(' ');
                int iYear = int.Parse(arrString[2]);
                iYear += 2000;

                int iMonth = int.Parse(arrString[1]);
                int iDay = int.Parse(arrString[0]);
                int iHour = int.Parse(arrString[3]);
                int iMinute = int.Parse(arrString[4]);
                int iSecond = int.Parse(arrString[5]);

                DateTime dtCreated = new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond, DateTimeKind.Utc);
                strReturn = dtCreated.ToLocalTime().ToString("ddd, d MMM yy HH:mm");
            }

                return strReturn;
        }

        public static string convertAPITimeToCuteTime(string strCreated)
        {
            string strReturn = "";

            if (!String.IsNullOrEmpty(strCreated))
            {
                //convert to local time
                //http://msdn.microsoft.com/en-us/library/1k1skd40.aspx <-didn't work for me
                //Mon, 21 Jun 10 13:52:41 +0000

                //21 Jun 10 13:52:41 +0000
                strCreated = strCreated.Remove(0, 5);

                //21 Jun 10 13:52:41
                strCreated = strCreated.Remove(strCreated.Length - 6, 6);

                strCreated = strCreated.Replace("Jan", "1");
                strCreated = strCreated.Replace("Feb", "2");
                strCreated = strCreated.Replace("Mar", "3");
                strCreated = strCreated.Replace("Apr", "4");
                strCreated = strCreated.Replace("May", "5");
                strCreated = strCreated.Replace("Jun", "6");
                strCreated = strCreated.Replace("Jul", "7");
                strCreated = strCreated.Replace("Aug", "8");
                strCreated = strCreated.Replace("Sep", "9");
                strCreated = strCreated.Replace("Oct", "10");
                strCreated = strCreated.Replace("Nov", "11");
                strCreated = strCreated.Replace("Dec", "12");

                strCreated = strCreated.Replace(":", " ");

                string[] arrString = strCreated.Split(' ');
                int iYear = int.Parse(arrString[2]);
                iYear += 2000;
                
                int iMonth = int.Parse(arrString[1]);
                int iDay = int.Parse(arrString[0]);
                int iHour = int.Parse(arrString[3]);
                int iMinute = int.Parse(arrString[4]);
                int iSecond = int.Parse(arrString[5]);

                DateTime dtCreated = new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond, DateTimeKind.Utc);
                DateTime dtNow = DateTime.Now.ToUniversalTime();
                TimeSpan tsDifference = dtNow - dtCreated;
                
                int iDays = System.Convert.ToInt32(tsDifference.TotalDays);

                if (iDays < 1)
                {
                    int iSeconds = System.Convert.ToInt32(tsDifference.TotalSeconds);
                    if ((iSeconds >= 0) && (iSeconds <= 60))
                    {
                        strReturn = "a few seconds ago";
                    }
                    else if ((iSeconds >= 61) && (iSeconds <= 120))
                    {
                        strReturn = "a minute ago";
                    }
                    else if ((iSeconds >= 121) && (iSeconds <= 3600))
                    {
                        strReturn = Math.Floor(iSeconds / 60) + " minutes ago";
                    }
                    else if ((iSeconds >= 3601) && (iSeconds <= 7200))
                    {
                        strReturn = "an hour ago";
                    }
                    else if ((iSeconds >= 7201) && (iSeconds <= 86400))
                    {
                        strReturn = Math.Floor(iSeconds / 3600) + " hours ago";
                    }
                }
                else if (iDays < 31)
                {
                    if (iDays == 1)
                    {
                        strReturn = "yesterday";
                    }
                    else if ((iDays >= 2) && (iDays <= 7))
                    {
                        strReturn = iDays + " days ago";
                    }
                    else if (iDays > 7)
                    {
                        double dblWeeks = Math.Ceiling(iDays / 7);
                        if (dblWeeks == 1)
                        {
                            strReturn = "1 week ago";
                        }
                        else
                        {
                            strReturn = dblWeeks + " weeks ago";
                        }
                    }
                }
                else
                {
                    strReturn = dtCreated.ToLocalTime().ToString("ddd, MMM d yyyy HH:mm");
                }
            }

            return strReturn;
        }

        public static string convertDistanceToKM(string strDistance)
        {
            string strReturn = "";

            if (!String.IsNullOrEmpty(strDistance))
            {
                float fMetres = float.Parse(strDistance);
                if (fMetres > 1000)
                {
                    float fKM = fMetres / 1000;
                    strReturn = fKM.ToString();

                    if (strReturn.Contains("."))
                    {
                        string[] arrString = strReturn.Split('.');
                        if (arrString[1].Length > 2)
                        {
                            int iNoOfChars = arrString[1].Length;
                            arrString[1] = arrString[1].Remove(1, iNoOfChars - 2);
                        }
                        
                        strReturn = arrString[0] + "." + arrString[1] + "km";
                    }
                    else
                    {
                        strReturn += "km";
                    }
                }
                else
                {
                    strReturn = strDistance + "m";
                }
            }

            return strReturn;
        }

        public static string buildAddress(XmlNode xmlVenue)
        {
            string strReturn = "";

            //address
            string strLabel = "";
            string strItem = "";

            //address
            strItem = Program.getInnerText(xmlVenue, "address");
            if (!String.IsNullOrEmpty(strItem))
            {
                strLabel += strItem + " ";
            }

            //crossstreet
            strItem = Program.getInnerText(xmlVenue, "crossstreet");
            if (!String.IsNullOrEmpty(strItem))
            {
                strLabel += "(" + strItem.Trim() + ") ";
            }

            //city
            strItem = Program.getInnerText(xmlVenue, "city");
            string strCity = strItem.Trim();
            if (!String.IsNullOrEmpty(strItem))
            {
                strLabel += strItem + " ";
            }

            //state
            strItem = Program.getInnerText(xmlVenue, "state");
            string strState = strItem.Trim();
            if (!String.IsNullOrEmpty(strItem))
            {
                if (!strCity.Equals(strState))
                {
                    strLabel += strItem + " ";
                }
            }

            //zip
            strItem = Program.getInnerText(xmlVenue, "zip");
            if (!String.IsNullOrEmpty(strItem))
            {
                strLabel += strItem + " ";
            }

            //phone
            strItem = Program.getInnerText(xmlVenue, "phone");
            if (!String.IsNullOrEmpty(strItem))
            {
                strLabel += "Phone: " + strItem + " ";
            }

            strReturn = strLabel.Trim();

            return strReturn;
        }

        //http://blogs.msdn.com/b/csharpfaq/archive/2006/10/09/how-do-i-calculate-a-md5-hash-from-a-string_3f00_.aspx
        public static string CalculateMD5Hash(string strInput)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(strInput);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));
            }

            return sb.ToString();
        }
    }
}